package com.storage.system.service.impl;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.storage.common.core.domain.AjaxResult;
import com.storage.common.core.domain.ServiceResponse;
import com.storage.common.core.page.TableDataInfo;
import com.storage.common.enums.RoleType;
import com.storage.common.utils.GsonUtil;
import com.storage.common.utils.StringUtils;
import com.storage.system.domain.StorageCategory;
import com.storage.system.domain.StorageProperties;
import com.storage.system.domain.StoragePropertiesValue;
import com.storage.system.domain.StorageUser;
import com.storage.system.mapper.StorageCategoryMapper;
import com.storage.system.mapper.StoragePropertiesMapper;
import com.storage.system.mapper.StoragePropertiesValueMapper;
import com.storage.system.service.IStoragePropertiesService;
import com.storage.system.vo.StoragePropertiesVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 属性 服务层实现
 *
 * @author storage
 * @date 2019-08-18
 */
@Service
public class StoragePropertiesServiceImpl implements IStoragePropertiesService {

    @Autowired
    private StoragePropertiesMapper storagePropertiesMapper;

    @Autowired
    private StoragePropertiesValueMapper storagePropertiesValueMapper;

    @Autowired
    private StorageCategoryMapper storageCategoryMapper;

    /**
     * 查询属性信息
     *
     * @param id 属性ID
     * @return 属性信息
     */
    @Override
    public StorageProperties selectStoragePropertiesById(Long id) {
        return storagePropertiesMapper.selectStoragePropertiesById(id);
    }

    /**
     * 查询属性列表
     *
     * @param categoryId 属性信息
     * @return 属性集合
     */
    @Override
    public ServiceResponse<TableDataInfo> selectStoragePropertiesList(StorageUser currentUser, Long categoryId, Integer pageNum, Integer pageSize) {
        Long operationUserId = RoleType.getOperationUserId(currentUser.getRole(), currentUser.getId(), currentUser.getShopId());
        StorageCategory category = null;
        String error = null;
        if (operationUserId == null) {
            error = "无操作权限";
        } else if ((category = storageCategoryMapper.selectStorageCategory(categoryId, operationUserId)) == null) {
            error = "分类不存在";
        }

        if (org.apache.commons.lang3.StringUtils.isNotBlank(error)) {
            return new ServiceResponse<>(false, null, error);
        }

        StorageProperties properties = new StorageProperties();
        properties.setCreateUserId(operationUserId);
        properties.setCategoryId(category.getId());
        properties.setOwnerType(RoleType.getOwnerType(currentUser.getRole()));

        if (pageNum == null) {
            pageNum = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }

        Integer start = (pageNum - 1) * pageSize;

        // 查询查询分页数据
        List<StorageProperties> propertiesList = storagePropertiesMapper.queryPageList(properties, start, pageSize);
        // 查询totalCount
        Long totalCount = storagePropertiesMapper.queryPageCount(properties);
        if (propertiesList == null || propertiesList.size() == 0) {
            TableDataInfo pageList = new TableDataInfo(new ArrayList<>(), totalCount, pageNum, pageSize);
            return new ServiceResponse<>(true, pageList, null);
        }

        List<StoragePropertiesVO> storagePropertiesVOS = propertiesList.stream().map(item -> wrapperStoragePropertiesDO(item, currentUser)).collect(Collectors.toList());
        TableDataInfo pageList = new TableDataInfo(storagePropertiesVOS, totalCount, pageNum, pageSize);
        return new ServiceResponse<>(true, pageList, null);
    }

    /**
     * 新增 / 修改属性
     *
     * @param storageProperties 属性信息 json
     * @return 结果
     */
    @Override
    public AjaxResult updateStorageProperties(StorageUser currentUser, String storageProperties, Long categoryId) {

        // 判断当前用户是否拥有对应分类
        StorageCategory condition = new StorageCategory();
        Long canOperationId = RoleType.getOperationUserId(currentUser.getRole(), currentUser.getId(), currentUser.getShopId());
        Integer ownerType = RoleType.getOwnerType(currentUser.getRole());
        if (canOperationId == null) {
            return AjaxResult.error("当前用不具备该操作权限");
        }

        Gson gson = GsonUtil.getGson();
        List<StoragePropertiesVO> storagePropertiesVOS = gson.fromJson(storageProperties, new TypeToken<List<StoragePropertiesVO>>() {}.getType());

        if (storagePropertiesVOS.isEmpty()) {
            // 删除当前分类下的所有属性以及属性选项
            List<StorageProperties> properties = storagePropertiesMapper.selectStoragePropertiesByCategoryId(categoryId, canOperationId, ownerType);
            if (!properties.isEmpty()) {
                for (StorageProperties item : properties) {
                    // 删除属性以及属性选项
                    storagePropertiesValueMapper.deleteStoragePropertiesValuePropertiesId(item.getId(), canOperationId, ownerType);
                    storagePropertiesMapper.deleteStoragePropertiesById(item.getId());
                }
            }
            return AjaxResult.success();
        }

        condition.setId(categoryId);
        condition.setCreateUserId(canOperationId);
        condition.setOwnerType(ownerType);
        List<StorageCategory> exists = storageCategoryMapper.selectStorageCategoryList(condition);
        if (exists == null || exists.size() == 0) {
            return AjaxResult.error("当前代理商或当前用户所属店铺不存在对应的分类");
        }

        // 根据最新传递的json数据为最新的属性以及属性选项数据，需要将最新的和原有的进行对比，将已删除的剔除掉
        ServiceResponse<List<StoragePropertiesVO>> sourcePropertiesVOS = selectStoragePropertiesList(currentUser, categoryId);

        Map<Long, List<Long>> newPropertiesMap = new HashMap<>();
        for (StoragePropertiesVO item : storagePropertiesVOS) {
            List<Long> newPropertiesValues = new ArrayList<>();
            StorageProperties storagePropertiesDO = item.toDO();
            storagePropertiesDO.setOwnerType(ownerType);
            storagePropertiesDO.setMultiChoice(item.getMultiChoice());
            if (item.getId() != null) {
                storagePropertiesMapper.updateStorageProperties(storagePropertiesDO);
            } else {
                storagePropertiesDO.setCreateUserId(canOperationId);
                storagePropertiesDO.setCategoryId(categoryId);
                storagePropertiesDO.setMultiChoice(item.getMultiChoice());
                storagePropertiesMapper.insertStorageProperties(storagePropertiesDO);
            }
            batchInsertPropertiesValues(storagePropertiesDO, item.getPropertiesValues(), newPropertiesValues);
            newPropertiesMap.put(storagePropertiesDO.getId(), newPropertiesValues);
        }

        // 计算要删除的属性以及属性选项
        Map<Long, List<Long>> removePropertiesMap = new HashMap<>();
        for (StoragePropertiesVO oldItem : sourcePropertiesVOS.getData()) {
            if (!newPropertiesMap.containsKey(oldItem.getId())) {
                removePropertiesMap.put(oldItem.getId(), null);
            } else {
                List<Long> removePropertiesValues = new ArrayList<>();
                List<Long> newPropertiesValues = newPropertiesMap.get(oldItem.getId());
                for (StoragePropertiesValue sourceValue : oldItem.getPropertiesValues()) {
                    if (!newPropertiesValues.contains(sourceValue.getId())) {
                        removePropertiesValues.add(sourceValue.getId());
                    }
                }
                removePropertiesMap.put(oldItem.getId(), removePropertiesValues);
            }
        }

        removePropertiesMap.forEach((propertiesId, propertiesValuesIdArr) -> {
            if (propertiesValuesIdArr == null) {
                // 删除当前属性和当前属性下的所有属性选项集合
                storagePropertiesMapper.deleteStoragePropertiesById(propertiesId);
            } else {
                // 删除属性选项集合
                if (propertiesValuesIdArr.size() > 0) {
                    for (Long propertiesValueId : propertiesValuesIdArr) {
                        // 删除对应的属性选项
                        storagePropertiesValueMapper.deleteStoragePropertiesValueById(propertiesValueId);
                    }
                }
            }

        });
        return AjaxResult.success("操作成功");
    }

    public ServiceResponse<List<StoragePropertiesVO>> selectStoragePropertiesList(StorageUser currentUser, Long categoryId) {
        Long operationUserId = RoleType.getOperationUserId(currentUser.getRole(), currentUser.getId(), currentUser.getShopId());
        StorageCategory category = null;
        String error = null;
        if (operationUserId == null) {
            error = "无操作权限";
        } else if ((category = storageCategoryMapper.selectStorageCategory(categoryId, operationUserId)) == null) {
            error = "分类不存在";
        }

        if (org.apache.commons.lang3.StringUtils.isNotBlank(error)) {
            return new ServiceResponse<>(false, null, error);
        }

        StorageProperties properties = new StorageProperties();
        properties.setCreateUserId(operationUserId);
        properties.setCategoryId(category.getId());
        properties.setOwnerType(RoleType.getOwnerType(currentUser.getRole()));

        List<StorageProperties> storagePropertiesList = storagePropertiesMapper.selectStoragePropertiesList(properties);
        if (storagePropertiesList.isEmpty()) {
            return new ServiceResponse<>(true, new ArrayList<>(), null);
        }

        List<StoragePropertiesVO> storagePropertiesVOS = storagePropertiesList.stream().map(item -> wrapperStoragePropertiesDO(item, currentUser)).collect(Collectors.toList());
        return new ServiceResponse<>(true, storagePropertiesVOS, null);
    }

    /**
     * 批量插入属性选项
     *
     * @param storagePropertiesDO
     * @param propertiesValues
     */
    private void batchInsertPropertiesValues(StorageProperties storagePropertiesDO, List<StoragePropertiesValue> propertiesValues,
                                             List<Long> newPropertiesValues) {
        if (storagePropertiesDO == null || propertiesValues == null || propertiesValues.size() == 0) {
            return;
        }

        for (StoragePropertiesValue propertiesValue : propertiesValues) {
            if (StringUtils.isBlank(propertiesValue.getPropertiesValue())) {
                continue;
            }
            if (propertiesValue.getId() != null) {
                storagePropertiesValueMapper.updateStoragePropertiesValue(propertiesValue);
            } else {
                propertiesValue.setPropertiesId(storagePropertiesDO.getId());
                propertiesValue.setCreateUserId(storagePropertiesDO.getCreateUserId());
                propertiesValue.setOwnerType(storagePropertiesDO.getOwnerType());
                storagePropertiesValueMapper.insertStoragePropertiesValue(propertiesValue);
            }
            newPropertiesValues.add(propertiesValue.getId());
        }
    }

    /**
     * 数据流转
     *
     * @param item
     * @param currentUser
     * @return
     */
    private StoragePropertiesVO wrapperStoragePropertiesDO(StorageProperties item, StorageUser currentUser) {

        StoragePropertiesValue condition = new StoragePropertiesValue();
        Long canOperationUserId = RoleType.getOperationUserId(currentUser.getRole(), currentUser.getId(), currentUser.getShopId());
        condition.setCreateUserId(canOperationUserId);
        condition.setPropertiesId(item.getId());
        condition.setOwnerType(RoleType.getOwnerType(currentUser.getRole()));
        List<StoragePropertiesValue> storagePropertiesValues = storagePropertiesValueMapper.selectStoragePropertiesValueList(condition);
        StoragePropertiesVO vo = new StoragePropertiesVO(item);
        vo.setPropertiesValues(storagePropertiesValues);
        return vo;
    }
}
